home *** CD-ROM | disk | FTP | other *** search
/ Mac Mania 5 / MacMania 5.toast / / Internet software / NewsWatcher / NW Source / Source / wind.c < prev    next >
Text File  |  1997-01-09  |  21KB  |  819 lines

  1. /*----------------------------------------------------------------------------
  2.  
  3.     wind.c
  4.  
  5.     This module handles the commands in the Windows menu. It also contains
  6.     a few general purpose window management functions.
  7.     
  8.     Copyright © 1994-1997, Northwestern University.
  9.  
  10. ----------------------------------------------------------------------------*/
  11.  
  12. #include <Icons.h>
  13. #include <stdio.h>
  14.  
  15. #include "glob.h"
  16. #include "full.h"
  17. #include "menus.h"
  18. #include "newswatcher.h"
  19. #include "wind.h"
  20. #include "dialog.h"
  21. #include "drawutil.h"
  22. #include "windutil.h"
  23. #include "memutil.h"
  24. #include "strutil.h"
  25. #include "header.h"
  26. #include "iconutil.h"
  27. #include "resutil.h"
  28. #include "fileutil.h"
  29. #include "help.h"
  30.  
  31.  
  32.  
  33. #define kOpenPadlockID                210
  34. #define kClosedPadlockID            211
  35.  
  36.  
  37.  
  38. /*----------------------------------------------------------------------------
  39.     DoCycleWindows 
  40.     
  41.     Handle the "Cycle Windows" command.
  42.     
  43.     Entry:    wind = pointer to window.
  44. ----------------------------------------------------------------------------*/
  45.  
  46. void DoCycleWindows (WindowPtr wind)
  47. {
  48.     SendBehind(wind, nil);
  49. }
  50.  
  51.  
  52.  
  53. /*----------------------------------------------------------------------------
  54.     DoZoomWindow 
  55.     
  56.     Handle the "Zoom Window" command.
  57.             
  58.     Entry:    wind = pointer to window.
  59.     
  60.     Exit:    function result = error code.
  61. ----------------------------------------------------------------------------*/
  62.  
  63. OSErr DoZoomWindow (WindowPtr wind)
  64. {
  65.     WStateData **wState;
  66.     Rect r;
  67.     OSErr err = noErr;
  68.  
  69.     wState = (WStateData**)((WindowPeek)wind)->dataHandle;
  70.     r = (**wState).stdState;
  71.     if (WindRectEqualRect(wind, &r)) {
  72.         err = DoZoom(wind, inZoomIn);
  73.     } else {
  74.         err = DoZoom(wind, inZoomOut);
  75.     }
  76.     return err;
  77. }
  78.  
  79.  
  80.  
  81. /*----------------------------------------------------------------------------
  82.     DoShowHideFullGroupList 
  83.     
  84.     Handle the "Show/Hide Full Group List" command.
  85.     
  86.     Exit:    function result = error code.
  87. ----------------------------------------------------------------------------*/
  88.  
  89. OSErr DoShowHideFullGroupList (void)
  90. {
  91.     OSErr err = noErr;
  92.  
  93.     if (((WindowPeek)gFullGroupWindow)->visible) {
  94.         HideWindow(gFullGroupWindow);
  95.         SetWindowsMenuShowHideFullGroupList(true);
  96.     } else {
  97.         if (gMustDoZoomOnShowFullGroupList) {
  98.             err = DoZoom(gFullGroupWindow, inZoomOut);
  99.             if (err != noErr) return err;
  100.         }
  101.         gMustDoZoomOnShowFullGroupList = false;
  102.         MyShowWindow(gFullGroupWindow);
  103.         SetWindowsMenuShowHideFullGroupList(false);
  104.         MySelectWindow(gFullGroupWindow);
  105.     }
  106.     return noErr;
  107. }
  108.  
  109.  
  110.  
  111. /*----------------------------------------------------------------------------
  112.     RebuildWindowsMenu
  113.     
  114.     Rebuild the list of open windows in the Windows menu.
  115. ----------------------------------------------------------------------------*/
  116.  
  117. void RebuildWindowsMenu (void)
  118. {
  119.     WindowPtr wind;
  120.     MenuHandle menu;
  121.     Str255 title;
  122.     Str255 menuStr;
  123.     short item, len, numItems, numDel;
  124.     TWindowKind kind;
  125.     TWindow **info;
  126.     Handle fullText;
  127.     CStr255 from;
  128.     
  129.     menu = GetMenuHandle(kWindMenu);
  130.     numItems = CountMItems(menu);
  131.     numDel = numItems - kFirstOpenWindItem + 1;
  132.     while (numDel--) DeleteMenuItem(menu, kFirstOpenWindItem);
  133.     item = kFirstOpenWindItem;
  134.     for (wind = FrontWindow(); 
  135.         wind != nil; 
  136.         wind = (WindowPtr)((WindowPeek)wind)->nextWindow) 
  137.     {
  138.         kind = GetMyWindowKind(wind);
  139.         if (kind != kNotOurWind && ((WindowPeek)wind)->visible) {
  140.             GetWTitle(wind, title);
  141.             len = *title;
  142.             if (len > 0 && title[1] == checkMark) {
  143.                 len--;
  144.                 BlockMoveData(title+2, title+1, len);
  145.                 *title = len;
  146.             }
  147.             if (kind == kArticle) {
  148.                 info = (TWindow**)GetWRefCon(wind);
  149.                 fullText = (**info).fullText;
  150.                 if (FindHeaderCString(fullText, "From", from, sizeof(from))) {
  151.                     FormatAuthorName(from);
  152.                     p2cstr(title);
  153.                     sprintf((char*)menuStr, "%.25s, %.200s", from, (char*)title);
  154.                     c2pstr((char*)menuStr);
  155.                 } else {
  156.                     CopyPascalString(menuStr, title);
  157.                 }
  158.             } else {
  159.                 CopyPascalString(menuStr, title);
  160.             }
  161.             len = *menuStr;
  162.             if (len > 200) {
  163.                 len = 200;
  164.                 *menuStr = len;
  165.             }
  166.             if (len > 0) {
  167.                 if (menuStr[1] == '-') {
  168.                     if (len < 255) len++;
  169.                     BlockMoveData(menuStr+1, menuStr+2, len-1);
  170.                     menuStr[1] = ' ';
  171.                     *menuStr = len;
  172.                 }
  173.             } else {
  174.                 *menuStr = 1;
  175.                 menuStr[1] = 'x';
  176.             }
  177.             AppendMenu(menu, "\px");
  178.             SetMenuItemText(menu, item, menuStr);
  179.             if (wind == FrontWindow()) CheckItem(menu, item, true);
  180.             item++;
  181.         }
  182.     }
  183. }
  184.  
  185.  
  186.  
  187. /*----------------------------------------------------------------------------
  188.     SelectWindMenu 
  189.     
  190.     Handle a window selection command in the Windows menu.
  191.             
  192.     Entry:    item = item number of menu command.
  193. ----------------------------------------------------------------------------*/
  194.  
  195. void SelectWindMenu (short item)
  196. {
  197.     WindowPtr wind;
  198.  
  199.     item -= kFirstOpenWindItem;
  200.     for (wind = FrontWindow();
  201.         wind != nil;
  202.         wind = (WindowPtr)((WindowPeek)wind)->nextWindow)
  203.     {
  204.         if (GetMyWindowKind(wind) != kNotOurWind && ((WindowPeek)wind)->visible) {
  205.             if (item <= 0) {
  206.                 MySelectWindow(wind);
  207.                 return;
  208.             } else {
  209.                 item--;
  210.             }
  211.         }
  212.     }
  213. }
  214.  
  215.  
  216.  
  217. /*----------------------------------------------------------------------------
  218.     GetMyWindowKind 
  219.     
  220.     Get the window kind.
  221.             
  222.     Entry:    wind = pointer to window.
  223.     
  224.     Exit:    function result = window kind.
  225. ----------------------------------------------------------------------------*/
  226.  
  227. TWindowKind GetMyWindowKind (WindowPtr wind)
  228. {
  229.     TWindow **info;
  230.     short windowKind;
  231.  
  232.     if (wind == nil) return kNotOurWind;
  233.     windowKind = ((WindowPeek)wind)->windowKind;
  234.     if (windowKind < 0) return kNotOurWind;
  235.     if (windowKind == dialogKind && wind != gMyCurDialog) return kNotOurWind;
  236.     info = (TWindow**)GetWRefCon(wind);
  237.     if (info == nil) return kNotOurWind;
  238.     return (**info).kind;
  239. }
  240.  
  241.  
  242.  
  243. /*----------------------------------------------------------------------------
  244.     CreateNewWindow
  245.     
  246.     Create a new window.
  247.     
  248.     Entry:    kind = window kind.
  249.             title = window title.
  250.             font = window font.
  251.             size = window font size.
  252.     
  253.     Exit:    function result = error code.
  254.             *theWindow = pointer to new window.
  255. ----------------------------------------------------------------------------*/
  256.  
  257. OSErr CreateNewWindow (TWindowKind kind, StringPtr title, 
  258.     StringPtr font, short size, WindowPtr *theWindow)
  259. {
  260.     WindowPtr wind = nil, prev, next, behind;
  261.     TWindow **info;
  262.     Rect bounds;
  263.     OSErr err = noErr;
  264.     short fontNum, wDefProcID;
  265.     GrafPtr port;
  266.     FontInfo fontInfo;
  267.     
  268.     GetPort(&port);
  269.         
  270.     SetRect(&bounds, 0, 0, 100, 100);
  271.     
  272.     /* Compute the window layer position. If the frontmost window belonging
  273.        to NewsWatcher is the status window, create the new window behind
  274.        the status window. Otherwise, create the new window in front of the
  275.        frontmost window belonging to NewsWatcher. */
  276.     
  277.     prev = nil;
  278.     next = FrontWindow();
  279.     while (next != nil && ((WindowPeek)next)->windowKind < 0) {
  280.         prev = next;
  281.         next = (WindowPtr)((WindowPeek)next)->nextWindow;
  282.     }
  283.     if (GetMyWindowKind(next) == kStatus) {
  284.         behind = next;
  285.     } else if (prev == nil) {
  286.         behind = (WindowPtr)-1;
  287.     } else {
  288.         behind = prev;
  289.     }
  290.     
  291.     wDefProcID = kind == kStatus ? movableDBoxProc : zoomDocProc;
  292.     err = MyNewWindow(&bounds, title, false, wDefProcID, behind, true, 0, &wind);
  293.     if (err != noErr) goto exit;
  294.     SetPort(wind);
  295.     
  296.     GetFontNumber(font, &fontNum);
  297.     TextFont(fontNum);
  298.     TextSize(size);
  299.  
  300.     err = MyNewHandle(sizeof(TWindow), &info);
  301.     if (err != noErr) goto exit;        
  302.     (**info).kind = kind;
  303.     SetWRefCon(wind, (long)info);
  304.     
  305.     GetFontInfo(&fontInfo);
  306.     (**info).fontInfo = fontInfo;
  307.     (**info).lineHeight = fontInfo.leading + fontInfo.ascent + fontInfo.descent;
  308.     
  309.     *theWindow = wind;
  310.     SetPort(port);
  311.     return noErr;
  312.  
  313. exit:
  314.  
  315.     MyDisposeWindow(wind);
  316.     SetPort(port);
  317.     return err;
  318. }
  319.  
  320.  
  321.  
  322. /*----------------------------------------------------------------------------
  323.     PositionNewWindow
  324.     
  325.     Position a new window.
  326.     
  327.     Entry:    wind = pointer to window.
  328.             width = window width.
  329.             height = window height.
  330. ----------------------------------------------------------------------------*/
  331.  
  332. void PositionNewWindow (WindowPtr wind, short width, short height)
  333. {
  334.     WindowPtr theWind;
  335.     WindowPeek theWindPeek;
  336.     TWindowKind kind;
  337.     
  338.     for (theWind = FrontWindow(); 
  339.         theWind != nil; 
  340.         theWind = (WindowPtr)((WindowPeek)theWind)->nextWindow) 
  341.     {
  342.         theWindPeek = (WindowPeek)theWind;
  343.         if (theWindPeek->windowKind < 0) continue;
  344.         if (theWind == wind) continue;
  345.         if (!theWindPeek->visible) continue;
  346.         kind = GetMyWindowKind(theWind);
  347.         if (kind == kStatus || kind == kNotOurWind || kind == kDummy) continue;
  348.         if (gStartingUp && theWind == gFullGroupWindow) continue;
  349.         break;
  350.     }
  351.  
  352.     StaggerWindow(wind, width, height, theWind, gPrefs.dontCoverFinderIcons);
  353. }
  354.  
  355.  
  356.  
  357. /*----------------------------------------------------------------------------
  358.     MyShowWindow
  359.     
  360.     Show a window.
  361.     
  362.     Entry:    wind = pointer to window.
  363. ----------------------------------------------------------------------------*/
  364.  
  365. void MyShowWindow (WindowPtr wind)
  366. {
  367.     EventRecord ev;
  368.     
  369.     if (gInBackground) HandleActivate(wind, false);
  370.     ShowWindow(wind);
  371.     while (WaitNextEvent(activMask | osMask, &ev, 0, nil))
  372.         HandleEvent(&ev);
  373. }
  374.  
  375.  
  376.  
  377. /*----------------------------------------------------------------------------
  378.     SaveWindPos
  379.     
  380.     Save a window position.
  381.     
  382.     Entry:    wind = pointer to window.
  383.     
  384.     Exit:    *pos = saved position.
  385. ----------------------------------------------------------------------------*/
  386.  
  387. void SaveWindPos (WindowPtr wind, TSavedWindPos *pos)
  388. {
  389.     TWindow **info;
  390.     GrafPtr port;
  391.     WStateData **wState;
  392.     Rect r, stdState;
  393.     
  394.     info = (TWindow**)GetWRefCon(wind);
  395.     if ((**info).windPosValid) {
  396.         GetPort(&port);
  397.         SetPort(wind);
  398.         pos->valid = true;
  399.         pos->oldFormat = false;
  400.         r = wind->portRect;
  401.         LocalToGlobalRect(&r);
  402.         wState = (WStateData**)((WindowPeek)wind)->dataHandle;
  403.         stdState = (**wState).stdState;
  404.         pos->zoomed = EqualRect(&stdState, &r);
  405.         if (pos->zoomed) {
  406.             pos->userState = (**wState).userState;
  407.         } else {
  408.             pos->userState = r;
  409.         }
  410.         SetPort(port);
  411.     } else {
  412.         pos->valid = false;
  413.     }
  414. }
  415.  
  416.  
  417.  
  418. /*----------------------------------------------------------------------------
  419.     RestoreWindPos
  420.     
  421.     Restore a window position.
  422.     
  423.     Entry:    wind = pointer to window.
  424.             pos = pointer to saved position.
  425.             
  426.     Exit:    *needsZooming = true if window should be zoomed.
  427. ----------------------------------------------------------------------------*/
  428.  
  429. void RestoreWindPos (WindowPtr wind, TSavedWindPos *pos, Boolean *needsZooming)
  430. {
  431.     TWindow **info;
  432.     GrafPtr port;
  433.     WStateData **wState;
  434.     Rect r;
  435.     Boolean mainScreen, onOneScreen, useDefaultPos;
  436.     short width, height;
  437.     
  438.     GetPort(&port);
  439.     SetPort(wind);
  440.     info = (TWindow**)GetWRefCon(wind);
  441.     
  442.     useDefaultPos = !pos->valid;
  443.     
  444.     if (!useDefaultPos) {
  445.         MoveWindow(wind, pos->userState.left, pos->userState.top, false);
  446.         if (pos->oldFormat) {
  447.             *needsZooming = true;
  448.         } else {
  449.             width = pos->userState.right - pos->userState.left;
  450.             height = pos->userState.bottom - pos->userState.top;
  451.             SizeWindow(wind, width, height, false);
  452.             *needsZooming = pos->zoomed;
  453.         }
  454.         if (!WindOnScreen(wind)) useDefaultPos = true;
  455.      }
  456.     
  457.     (**info).windPosValid = !useDefaultPos; 
  458.     
  459.     if (useDefaultPos) {
  460.         if ((**info).kind == kGroup && (**info).groupKind == kFullGroup) {
  461.             MoveWindow(wind, 10, GetMBarHeight() + 30, false);
  462.             GetDominantScreen(gFullGroupWindow, &r, &mainScreen, &onOneScreen);
  463.             MoveWindow(wind, r.right - wind->portRect.right - 64,
  464.                 r.top + GetMBarHeight() + 30, false);
  465.         } else {
  466.             PositionNewWindow(wind, wind->portRect.right, wind->portRect.bottom);
  467.         }
  468.         *needsZooming = true;
  469.     }
  470.         
  471.     wState = (WStateData**)((WindowPeek)wind)->dataHandle;
  472.     r = wind->portRect;
  473.     LocalToGlobalRect(&r);
  474.     (**wState).userState = r;
  475.     
  476.     SetPort(port);
  477. }
  478.  
  479.  
  480.  
  481. /*----------------------------------------------------------------------------
  482.     SaveWindPosAsResource
  483.     
  484.     Save a window position as a 'WPOS' id=128 resource on the current
  485.     resource file.
  486.     
  487.     Entry:    wind = pointer to window.
  488.     
  489.     Exit:    function result = error code.
  490. ----------------------------------------------------------------------------*/
  491.  
  492. OSErr SaveWindPosAsResource (WindowPtr wind)
  493. {
  494.     TSavedWindPos pos;
  495.     Handle h = nil;
  496.     OSErr err = noErr;
  497.     TWindow **info;
  498.     
  499.     SaveWindPos(wind, &pos);
  500.     err = MyPtrToHand(&pos, &h, sizeof(pos));
  501.     if (err != noErr) goto exit;
  502.     err = MyReplaceResource(h, 'WPOS', 128, "\p");
  503.     if (err != noErr) goto exit;
  504.     info = (TWindow**)GetWRefCon(wind);
  505.     (**info).movedSinceLastSave = false;
  506.     return noErr;
  507.     
  508. exit:
  509.  
  510.     MyDisposeHandle(h);
  511.     return err;
  512. }
  513.  
  514.  
  515.  
  516. /*----------------------------------------------------------------------------
  517.     SaveWindPosToFile
  518.     
  519.     If necessary, save just a changed window position to a document file,
  520.     without changing the window's last mod date.
  521.     
  522.     Entry:    wind = pointer to window.
  523.     
  524.     Exit:    function result = error code.
  525. ----------------------------------------------------------------------------*/
  526.  
  527. OSErr SaveWindPosToFile (WindowPtr wind)
  528. {
  529.     TWindow **info;
  530.     AliasHandle alias;
  531.     FSSpec fSpec;
  532.     OSErr err = noErr;
  533.     Boolean wasChanged;
  534.     short refNum = 0;
  535.     unsigned long lastModDateTime;
  536.     FInfo fInfo;
  537.     
  538.     /* Note that errors are ignored. This is not a critical operation,
  539.        and we don't want to interfere with closing a window just because
  540.        something fails here. */
  541.     
  542.     info = (TWindow**)GetWRefCon(wind);
  543.     alias = (**info).alias;
  544.     if (alias == nil || !(**info).movedSinceLastSave) return noErr;
  545.     err = ResolveAlias(nil, alias, &fSpec, &wasChanged);
  546.     if (err != noErr) return noErr;
  547.     err = FSpGetFInfo(&fSpec, &fInfo);
  548.     if (err != noErr) return noErr;
  549.     if (fInfo.fdCreator != kNewsWatcherSignature) return noErr;
  550.     err = GetLastModDateTime(&fSpec, &lastModDateTime);
  551.     if (err != noErr) return noErr;
  552.     err = MyFSpOpenResFile(&fSpec, fsRdWrPerm, &refNum);
  553.     if (err != noErr) return noErr;
  554.     err = SaveWindPosAsResource(wind);
  555.     if (err != noErr) goto exit;
  556.     MyCloseResFile(refNum);
  557.     err = SetLastModDateTime(&fSpec, lastModDateTime);
  558.     return noErr;
  559.     
  560. exit:
  561.  
  562.     if (refNum != 0) MyCloseResFile(refNum);
  563.     return noErr;
  564. }
  565.  
  566.  
  567.  
  568. /*----------------------------------------------------------------------------
  569.     RestoreLockedWindowPosition
  570.     
  571.     Restore a locked window position.
  572.     
  573.     Entry:    wind = pointer to subject, article, or message window.
  574.             width = unlocked width of window.
  575.             height = unlocked height of window.
  576.             windPosLocked = true if this kind of window has a saved
  577.                 locked position.
  578.             *windLocn = saved locked window position.
  579.             
  580.     If this kind of window has a saved locked window position, and if
  581.     no other window of this kind is already open, the saved locked window
  582.     position is restored. Otherwise, the default window postion is set.
  583. ----------------------------------------------------------------------------*/
  584.  
  585. void RestoreLockedWindowPosition (WindowPtr wind, short width, short height,
  586.     Boolean windPosLocked, Rect *windLocn)
  587. {
  588.     TWindow **info;
  589.     TWindowKind kind;
  590.     WindowPtr w;
  591.     GrafPtr port;
  592.     WStateData **wState;
  593.     Rect r;
  594.     
  595.     GetPort(&port);
  596.     SetPort(wind);
  597.  
  598.     info = (TWindow**)GetWRefCon(wind);
  599.     kind = (**info).kind;
  600.     
  601.     if (windPosLocked) {
  602.         for (w = FrontWindow(); w != nil; w = (WindowPtr)((WindowPeek)w)->nextWindow) {
  603.             if (kind == GetMyWindowKind(w) && w != wind) {
  604.                 windPosLocked = false;
  605.                 break;
  606.             }
  607.         }
  608.     }
  609.     
  610.     if (windPosLocked) {
  611.         MoveWindow(wind, windLocn->left, windLocn->top, false);
  612.         SizeWindow(wind, windLocn->right - windLocn->left, 
  613.             windLocn->bottom - windLocn->top, false);
  614.         if (WindOnScreen(wind)) {
  615.             wState = (WStateData**)((WindowPeek)wind)->dataHandle;
  616.             r = wind->portRect;
  617.             LocalToGlobalRect(&r);
  618.             (**wState).userState = r;
  619.         } else {
  620.             windPosLocked = false;
  621.         }
  622.     }
  623.     
  624.     if (!windPosLocked) {
  625.         PositionNewWindow(wind, width, height);
  626.     }
  627.     
  628.     (**info).windPosLocked = windPosLocked;
  629.     
  630.     SetPort(port);
  631. }
  632.  
  633.  
  634.  
  635. /*----------------------------------------------------------------------------
  636.     DrawPadlockIcon
  637.     
  638.     Draw the padlock icon in a window.
  639.     
  640.     Entry:    wind = pointer to subject, article, or message window.
  641. ----------------------------------------------------------------------------*/
  642.  
  643. void DrawPadlockIcon (WindowPtr wind)
  644. {
  645.     TWindow **info;
  646.     short windHeight;
  647.     Rect padlockRect;
  648.  
  649.     info = (TWindow**)GetWRefCon(wind);
  650.     windHeight = wind->portRect.bottom;
  651.     SetRect(&padlockRect, 1, windHeight-17, 17, windHeight-1); 
  652.     PlotIconID(&padlockRect, 0, ttNone, 
  653.         (**info).windPosLocked ? kClosedPadlockID : kOpenPadlockID);
  654. }
  655.  
  656.  
  657.  
  658. /*----------------------------------------------------------------------------
  659.     HandlePadlockClick
  660.     
  661.     Check for and handle a click on a padlock icon.
  662.     
  663.     Entry:    wind = pointer to subject, article, or message window.
  664.             where = location of mouse down event, in local coords.
  665.             windPosLocked = pointer to windPosLocked preference for
  666.                 this kind of window.
  667.             windLocn = pointer to saved locked window position for
  668.                 this kind of window.
  669.                 
  670.     Exit:    function result = true if padlock clicked.
  671. ----------------------------------------------------------------------------*/
  672.  
  673. Boolean HandlePadlockClick (WindowPtr wind, Point where, 
  674.     Boolean *windPosLocked, Rect *windLocn)
  675. {
  676.     TWindow **info;
  677.     short windHeight, iconID;
  678.     Rect padlockRect, hotRect;
  679.     GrafPtr port;
  680.     WindowPtr w;
  681.     TWindowKind kind;
  682.  
  683.     GetPort(&port);
  684.     SetPort(wind);
  685.     
  686.     info = (TWindow**)GetWRefCon(wind);
  687.     windHeight = wind->portRect.bottom;
  688.     SetRect(&padlockRect, 0, windHeight-16, 16, windHeight); 
  689.     hotRect = padlockRect;
  690.     hotRect.top += 2;
  691.     hotRect.right -= 1;
  692.     iconID = (**info).windPosLocked ? kClosedPadlockID : kOpenPadlockID;
  693.     
  694.     if (!TrackIconClick(where, &padlockRect, &hotRect, iconID)) {
  695.         SetPort(port);
  696.         return false;
  697.     }
  698.     
  699.     SetRect(&padlockRect, 0, windHeight - 13, 13, windHeight);
  700.     
  701.     (**info).windPosLocked = *windPosLocked = !(**info).windPosLocked;
  702.     InvalRect(&padlockRect);
  703.     if (*windPosLocked) {
  704.         *windLocn = wind->portRect;
  705.         LocalToGlobalRect(windLocn);
  706.         SetPort(port);
  707.         kind = (**info).kind;
  708.         for (w = FrontWindow(); w != nil; w = (WindowPtr)((WindowPeek)w)->nextWindow) {
  709.             if (kind == GetMyWindowKind(w) && w != wind) {
  710.                 info = (TWindow**)GetWRefCon(w);
  711.                 if ((**info).windPosLocked) {
  712.                     (**info).windPosLocked = false;
  713.                     SetPort(w);
  714.                     windHeight = w->portRect.bottom;
  715.                     SetRect(&padlockRect, 0, windHeight - 13, 13, windHeight);
  716.                     InvalRect(&padlockRect);
  717.                 }
  718.             }
  719.         }
  720.     }
  721.     KillBalloon();
  722.     SetPort(port);
  723.     return true;
  724. }
  725.  
  726.  
  727.  
  728. /*----------------------------------------------------------------------------
  729.     RecordNewLockedWindowPosition
  730.     
  731.     Record the new locked window position after a locked window is resized.
  732.     
  733.     Entry:    wind = pointer to subject, article, or message window.
  734.             windLocn = pointer to saved locked window position for
  735.                 this kind of window.
  736.                 
  737.     Exit:    *windLocn = new locked window position.
  738. ----------------------------------------------------------------------------*/
  739.  
  740. void RecordNewLockedWindowPosition (WindowPtr wind, Rect *windLocn)
  741. {
  742.     TWindow **info;
  743.     GrafPtr port;
  744.     
  745.     info = (TWindow**)GetWRefCon(wind);
  746.     if (!(**info).windPosLocked) return;
  747.     *windLocn = wind->portRect;
  748.     GetPort(&port);
  749.     SetPort(wind);
  750.     LocalToGlobalRect(windLocn);
  751.     SetPort(port);
  752. }
  753.  
  754.  
  755.  
  756. /*----------------------------------------------------------------------------
  757.     MySelectWindow
  758.     
  759.     Move a window to the front, or just behind the Status window if the
  760.     Status window is open.
  761.     
  762.     Entry:    wind = pointer to window.
  763. ----------------------------------------------------------------------------*/
  764.  
  765. void MySelectWindow (WindowPtr wind)
  766. {
  767.     WindowPtr front;
  768.     WindowRef wRef;
  769.  
  770.     front = MyFrontWindow();
  771.     if (GetMyWindowKind(front) == kStatus) {
  772.         wRef = (WindowRef)wind;
  773.         PaintOne(wRef, ((WindowPeek)wRef)->strucRgn);
  774.         CalcVis(wRef);
  775.         SendBehind(wind, front);
  776.     } else {
  777.         SelectWindow(wind);
  778.     }
  779. }
  780.  
  781.  
  782.  
  783. /*----------------------------------------------------------------------------
  784.     AdjustWindowTitlesOnResume
  785.     
  786.     Adjust the titles of all open windows which correspond to saved files
  787.     on a resume event, in case the user changed the file names.
  788. ----------------------------------------------------------------------------*/
  789.  
  790. void AdjustWindowTitlesOnResume (void)
  791. {
  792.     WindowPtr wind;
  793.     TWindowKind kind;
  794.     TWindow **info;
  795.     FSSpec fSpec;
  796.     Boolean wasChanged;
  797.     OSErr err = noErr;
  798.     Str255 title;
  799.  
  800.     for (wind = FrontWindow(); 
  801.         wind != nil; 
  802.         wind = (WindowPtr)((WindowPeek)wind)->nextWindow) 
  803.     {
  804.         kind = GetMyWindowKind(wind);
  805.         if (kind != kGroup && kind != kMessage) continue;
  806.         info = (TWindow**)GetWRefCon(wind);
  807.         if ((**info).alias == nil) continue;
  808.         err = ResolveAlias(nil, (**info).alias, &fSpec, &wasChanged);
  809.         if (err == noErr) {
  810.             GetWTitle(wind, title);
  811.             if (EqualString(title, fSpec.name, false, true)) continue;
  812.             SetWTitle(wind, fSpec.name);
  813.         } else {
  814.             MyDisposeHandle((**info).alias);
  815.             (**info).alias = nil;
  816.             (**info).changed = true;
  817.         }
  818.     }
  819. }